package org.lfs.operations;

import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import org.apache.poi.xwpf.usermodel.*;

import javax.swing.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class FileOperations {

    public static void selectAndFlattenAndCopyFiles() {
        File selectedDir = selectDirectory();
        if (selectedDir != null) {
            try {
                flattenAndCopyFiles(selectedDir);
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, "复制文件时发生错误: " + ex.getMessage());
            }
        }
    }

    public static void selectAndExtractContent(String type) {
        File selectedDir = selectDirectory();
        if (selectedDir != null) {
            try {
                switch (type) {
                    case "Java":
                        int option = JOptionPane.showOptionDialog(null, "是否去掉import内容？",
                                "去掉import内容", JOptionPane.YES_NO_OPTION,
                                JOptionPane.QUESTION_MESSAGE, null,
                                new Object[]{"是", "否"}, "否");
                        boolean removeImports = (option == JOptionPane.YES_OPTION);

                        extractAndFilterContent(selectedDir, new String[]{".java"},
                                removeImports ? line -> !line.matches("^import .*;$") : null,
                                "_java.txt");
                        break;
                    case "Python":
                        extractAndFilterContent(selectedDir, new String[]{".py"}, null, "_python.txt");
                        break;
                    case "H5":
                        extractAndFilterContent(selectedDir, new String[]{".html", ".htm", ".js", ".css"}, null, "_h5.txt");
                        break;
                }
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, "提取内容时发生错误: " + ex.getMessage());
            }
        }
    }

    private static File selectDirectory() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
            return fileChooser.getSelectedFile();
        }
        return null;
    }

    private static void flattenAndCopyFiles(File dir) throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String newDirName = dir.getName() + "_" + timeStamp;
        File newDir = new File(dir.getParentFile(), newDirName);

        if (!newDir.mkdir()) {
            throw new IOException("无法创建新目录");
        }

        Files.walk(dir.toPath())
                .filter(Files::isRegularFile)
                .forEach(source -> {
                    try {
                        Path targetPath = newDir.toPath().resolve(source.getFileName());
                        Files.copy(source, targetPath, StandardCopyOption.REPLACE_EXISTING);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });

        JOptionPane.showMessageDialog(null, "文件复制完成！");
    }


    private static void extractAndFilterContent(File dir, String[] extensions, Predicate<String> lineFilter, String outputSuffix) throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        Path contentFilePath = Paths.get(dir.getParentFile().toString(), timeStamp + outputSuffix);

        StringBuilder contentBuilder = new StringBuilder();

        extractContent(dir, extensions, file -> {
            String fileContent = readFileContent(file.toPath(), lineFilter);
            contentBuilder.append(fileContent);
        });

        writeFileContent(contentFilePath, contentBuilder.toString());
        JOptionPane.showMessageDialog(null, "内容提取完成！");
    }

    private static void extractContent(File dir, String[] extensions, Consumer<File> fileProcessor) throws IOException {
        Files.walk(dir.toPath())
                .filter(Files::isRegularFile)
                .filter(path -> Arrays.stream(extensions).anyMatch(ext -> path.toString().endsWith(ext)))
                .forEach(source -> {
                    try {
                        fileProcessor.accept(source.toFile());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
    }

    private static String readFileContent(Path filePath, Predicate<String> lineFilter){
        StringBuilder content = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(filePath), StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (lineFilter == null || lineFilter.test(line)) {
                    content.append(line).append("\n");
                }
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
        return content.toString();
    }

    private static void writeFileContent(Path filePath, String content) throws IOException {
        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(filePath), StandardCharsets.UTF_8))) {
            writer.write(content);
        }
    }

    public void processMinioTemplate(String[] info, String[] contents) {
        try {
            MinioClient minioClient = MinioClient.builder()
                    .endpoint("http://10.0.25.150:9000")
                    .credentials("erdp_test", "test@erdp@minio@2022")
                    .build();

            String bucketName = "fas";
            String objectName = "/template/patent.docx";
            Path tempFilePath = Paths.get("tempTemplate.docx");

            try (InputStream stream = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .build())) {

                try (FileOutputStream out = new FileOutputStream(tempFilePath.toFile())) {
                    byte[] buffer = new byte[8192];
                    int bytesRead;
                    while ((bytesRead = stream.read(buffer)) != -1) {
                        out.write(buffer, 0, bytesRead);
                    }
                }
            }

            // 使用 Apache POI 处理文档
            try (XWPFDocument doc = new XWPFDocument(java.nio.file.Files.newInputStream(tempFilePath))) {
                insertTextWithNewLines(doc.getTables().get(0).getRow(2).getCell(1), info[0]); // 姓名工号
                insertTextWithNewLines(doc.getTables().get(0).getRow(2).getCell(3), info[1]); // 手机
                insertTextWithNewLines(doc.getTables().get(0).getRow(2).getCell(4), info[2]); // 邮箱
                insertTextWithNewLines(doc.getTables().get(0).getRow(3).getCell(1), info[3]); // 标题
                insertTextWithNewLines(doc.getTables().get(0).getRow(6).getCell(0), contents[0]); // 技术领域
                insertTextWithNewLines(doc.getTables().get(0).getRow(9).getCell(0), contents[1]); // 现有技术
                insertTextWithNewLines(doc.getTables().get(0).getRow(12).getCell(0), contents[2]); // 缺陷
                insertTextWithNewLines(doc.getTables().get(0).getRow(15).getCell(0), contents[3]); // 技术方案详述
                insertTextWithNewLines(doc.getTables().get(0).getRow(18).getCell(0), contents[4]); // 有益的技术效果
                insertTextWithNewLines(doc.getTables().get(0).getRow(21).getCell(0), contents[5]); // 保护点
                insertTextWithNewLines(doc.getTables().get(0).getRow(24).getCell(0), contents[6]); // 可替代方案
                insertTextWithNewLines(doc.getTables().get(0).getRow(30).getCell(0), contents[7]); // 补充的技术方案信息

                // Save to desktop
                Path desktopPath = Paths.get(System.getProperty("user.home"), "Downloads", "".equals(info[3]) ? "【秘密】专利交底书.docx" : ("【秘密】" + info[3] + ".docx"));
                try (FileOutputStream out = new FileOutputStream(desktopPath.toFile())) {
                    doc.write(out);
                }
            }

            JOptionPane.showMessageDialog(null, "文档已生成并保存到下载目录！");
        } catch (Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "发生错误: " + e.getMessage());
        }
    }

    /**
     * 换行处理
     * @param cell
     * @param text
     */
    private void insertTextWithNewLines(XWPFTableCell cell, String text) {
        cell.removeParagraph(0);

        String[] lines = text.split("\n");
        for (String line : lines) {
            XWPFParagraph paragraph = cell.addParagraph();
            XWPFRun run = paragraph.createRun();
            run.setText(line);
//            run.addBreak();
        }
    }
}
